package ginserver

import (
	"fmt"
	"log"
	"net/http"
	"strconv"
	"time"

	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"

	"go-base/configs"
	_ "go-base/docs"
	"go-base/internal/api"

	"github.com/gin-gonic/gin"
)

// Run
// 启动路由
func Run() {
	log.Printf("启动路由")
	// 设置Gin的运行模式为发布模式
	gin.SetMode(gin.ReleaseMode)

	// ginserver := gin.Default() // 初始化Gin引擎
	router := gin.New()
	server := &http.Server{
		Addr:           "0.0.0.0:" + strconv.Itoa(int(configs.Data.Gin.Port)),
		Handler:        router,          // 路由
		ReadTimeout:    5 * time.Second, // 读取超时时间
		WriteTimeout:   5 * time.Second, // 写入超时时间
		MaxHeaderBytes: 1 << 20,         // 1 MB // 最大请求头字节数

	}
	// 使用中间件
	allowCORSMiddleware(router)        // 忽略跨域中间件，允许所有跨域请求
	forceHttpsMiddleware(router)       // 强制要求使用HTTPS的中间件
	noRouterResponseMiddleware(router) // 配置统一处理无路由的情况

	// 初始化中间件，指定不记录日志的路由和方法
	notLogged := []routeInfo{
		{Method: http.MethodGet, Path: "/swagger/*any"},
		{Method: http.MethodHead, Path: "/api/available"},
		{Method: http.MethodHead, Path: "/api/icafe/go-base"},
		{Method: http.MethodPost, Path: "/api/icafe/device/temperature"},
		// 可以在这里添加更多的路由规则
	}
	router.Use(CustomLogMiddleware(notLogged))

	router.Use(AuthMiddleware()) // 验证Token的中间件
	// 忽略参数及路径中的大小写问题，以避免无法正确获取到路由参数的问题
	router.Use(NormalizeParamsMiddleware())

	gin.Recovery()

	// 使用以下行添加 Swagger 的路由
	router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

	// 注册路由
	registerRouter(router)

	// 监听IPv4地址上的HTTPS服务
	if err := server.ListenAndServeTLS("server.crt", "server.key"); err != nil {
		panic(fmt.Sprintf("Gin出错了：%v\n", err))
	}
}

// registerRouter 注册路由
func registerRouter(router *gin.Engine) {
	// api路由
	apiRouter := router.Group("/api")
	{
		// 接口是否可用
		apiRouter.GET("/available", api.AvailableHandle)
		// 区域路由
		areaRouter := apiRouter.Group("/areas")
		{
			areaRouter.GET("/provinces", api.QueryProvincesHandle)
			areaRouter.GET("/cities/:ProvinceID", api.QueryCitiesByProvinceIdHandle)
			areaRouter.GET("/counties/:CityID", api.QueryCountiesByCiteIdHandle)
			areaRouter.GET("/upper/:AreaID", api.QueryUpperIdByAreaIdHandle)
			areaRouter.GET("/province/:Keyword", api.SearchProvinceByKewordHandle)
			areaRouter.GET("/provinces/:Keyword", api.SearchProvincesByKewordHandle)
			areaRouter.GET("/city/:ProvinceID/:Keyword", api.SearchCityByProvinceIdAndKeywordHandle)
			areaRouter.GET("/cities/:ProvinceID/:Keyword", api.SearchCitiesByProvinceIdAndKeywordHandle)
			areaRouter.GET("/region", api.QueryClientIpRegionHandle)
		}
		userRouter := apiRouter.Group("/users")
		{
			userRouter.GET("/:phone", api.GetUserHandler)
			userRouter.GET("/", api.ListUsersHandler)
		}
	}
}
